#include<iostream>
#include "winsock2.h"
#include<fstream>
#define PORT 65432
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#pragma comment(lib, "ws2_32.lib")
using namespace std;

struct fileMessage {
	char fileName[256];
	long fileSize;
};


int main()
{
	int sock_client;  //定义客户端套接字
	struct sockaddr_in server_addr; //定义存放服务器端地址的结构变量
	int addr_len = sizeof(struct sockaddr_in); //地址结构变量长度
	char msgbuffer[1000]; //接收/发送信息的缓冲区
	/***初始化winsock DLL***/
	WSADATA wsaData;
	WORD wVersionRequested = MAKEWORD(2, 2);
	if (WSAStartup(wVersionRequested, &wsaData) != 0)
	{
		cout << "加载winsock.dll失败！\n";
		return 0;
	}
	/***创建套接字***/
	if ((sock_client = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		cout << "创建套接字失败！错误代码:" << WSAGetLastError() << endl;
		WSACleanup();
		return 0;
	}
	/***填写服务器地址***/
	char IP[20];
	cout << "请输入服务器IP地址：";
	cin >> IP;
	memset((void*)&server_addr, 0, addr_len);
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(PORT);
	server_addr.sin_addr.s_addr = inet_addr(IP);//填写服务器IP地址
	/***与服务器建立连接***/
	if (connect(sock_client, (struct sockaddr*)&server_addr, addr_len) != 0)
	{
		cout << "连接失败！错误代码:" << WSAGetLastError() << endl;
		closesocket(sock_client);
		WSACleanup();
		return 0;
	}
	/***接收信息并显示***/
	int size = recv(sock_client, msgbuffer, sizeof(msgbuffer), 0);
	if (size < 0) {
		cout << "接收信息失败！错误代码:" << WSAGetLastError() << endl;
		closesocket(sock_client);//关闭已连接套接字
		WSACleanup(); //注销WinSock动态链接库
		return 0;
	}
	else if (size == 0) {
		cout << "对方已关闭连接！\n";
		closesocket(sock_client);
		WSACleanup();
		return 0;
	}
	else
		cout << "服务器来消息啦： " << msgbuffer << endl;

	struct fileMessage file;
	long  filelen;
	char fileName[255] = { '\0' };
	char buffer[1000];

	if ((filelen = recv(sock_client, (char*)&file, sizeof(file), 0)) <= 0) {
		cout << "未接收到文件名及文件长度！" << endl;
		closesocket(sock_client);
		WSACleanup();
		return 0;
	}
	filelen = file.fileSize;
	strcpy(fileName, file.fileName);
	ofstream outFile(fileName, ios::out | ios::binary);
	if (!outFile.is_open()) {
		cout << "文件不能打开!" << fileName << endl;
		closesocket(sock_client);
		WSACleanup();
		return 0;
	}
	do {
		size = recv(sock_client, buffer, sizeof(buffer), 0);
		if (size <= 0) {
			break;
		}
		outFile.write(buffer, size);
		filelen -= size;
	} while (filelen > 0);
	if (filelen == 0) {
		cout << "文件传输完毕!" << endl;
	}
	else {
		cout << "文件传输失败!" << endl;
	}
	outFile.close();
	closesocket(sock_client); //关闭socket
	WSACleanup(); //注销WinSock动态链接库
	return 0;
}
